﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Boom.Navigation;

namespace Boom.GameObjects
{
    public abstract class GameObject : MultilFrame
    {
        protected Vector2 _Speed;
        protected bool _Move;
        protected int _VectorA;
        protected int _Power;
        protected int _Hp;
        protected int _Status;
        protected bool _Immortal;

        protected int _FrameBlock;
        protected int _FrameDead;
        protected bool _ChangeFrame;
        protected int _FrameChangeStt;
        
        private TimeSpan ElapsedTime = TimeSpan.Zero;
        private TimeSpan _ElapsedTimeChange;
        private TimeSpan _ElapsedTimeImmortal;


        public int Power
        {
            get { return _Power; }
            set { _Power = value; }
        }

        public Vector2 Speed
        {
            get { return _Speed; }
            set { _Speed = value; }
        }

        public bool Move
        {
            get { return _Move; }
            set { _Move = value; }
        }

        public int VectorA
        {
            get { return _VectorA; }
            set { _VectorA = value; }

        }

        public int HP
        {
            get { return _Hp; }
            set { _Hp = value; }
        }

        public int Status
        {
            get { return _Status; }
            set { _Status = value; }  
        }

        //Biến logic điều khiển trong khoảng thời gian làm bất tử đối với nhân vật và dừng động tác đối với quái vật
        //khi giảm HP
        public bool Immortal
        {
            get { return _Immortal; }
            set { _Immortal = value; }
        }

        //Khối hình di chuyển 4 hướng
        protected int FrameBlock
        {
            get { return _FrameBlock; }
            set { _FrameBlock = value; }
        }

        public bool ChangeFrame
        {
            get { return _ChangeFrame; }
            set
            {
                if (value)
                {
                    FrameBlock = _HoriFrame * 4;
                }
                else
                {
                    FrameBlock = 0;
                }
                _ChangeFrame = value;
            }
        }

        public GameObject(Game Mygame, Vector2 Position, ref Texture2D Texture, int Width, int Height)
            : base(Mygame, ref Texture, Width, Height)
        {
            this.Position = Position;
            _ElapsedTimeChange = TimeSpan.Zero;
            _ElapsedTimeImmortal = TimeSpan.Zero;
        }

        //Chuyển frame trong khoảng 

        protected void ChangeFrameOf(GameTime gameTime, int MinFrame, int MaxFrame, int TimeChange)
        {
            if (_ActiveFrame < MinFrame || _ActiveFrame >= MaxFrame) _ActiveFrame = MinFrame;
            ElapsedTime += gameTime.ElapsedGameTime;
            if (ElapsedTime > TimeSpan.FromMilliseconds(TimeChange))
            {
                ElapsedTime -= TimeSpan.FromMilliseconds(TimeChange);
                _ActiveFrame++;
            }
        }

        //Chuyển frame và di chuyển về bên trái
        protected void MoveLeft(GameTime gameTime)
        {
            Speed = new Vector2(-Power, 0);
            VectorA = 1;
            ChangeFrameOf(gameTime, _FrameBlock ,_HoriFrame - 1 + _FrameBlock, (int)(200 - 30 * Math.Abs((Speed.X + Speed.Y))));
        }

        //Chuyển frame và di chuyển lên trên
        protected void MoveUp(GameTime gameTime)
        {
            Speed = new Vector2(0, -Power);
            VectorA = 2;
            ChangeFrameOf(gameTime, _HoriFrame + _FrameBlock, _HoriFrame * 2 - 1 + _FrameBlock, (int)(200 - 30 * Math.Abs((Speed.X + Speed.Y))));
        }

        //Chuyển frame và di chuyển về bên phải
        protected void MoveRight(GameTime gameTime)
        {
            Speed = new Vector2(Power, 0);
            VectorA = 3;
            ChangeFrameOf(gameTime, _HoriFrame * 2 + FrameBlock, _HoriFrame * 3 - 1 + FrameBlock, (int)(200 - 30 * Math.Abs((Speed.X + Speed.Y))));
        }

        //Chuyển frame và di chuyển xuống dưới
        protected void MoveDown(GameTime gameTime)
        {
            Speed = new Vector2(0, Power);
            VectorA = 4;
            ChangeFrameOf(gameTime, _HoriFrame * 3 + FrameBlock, _HoriFrame * 4 - 1 + FrameBlock, (int)(200 - 30 * Math.Abs((Speed.X + Speed.Y))));
        }

        //Khi đối tượng giảm máu hoặc mạng
        private void HpDown(GameTime gameTime)
        {
            Move = false;
            ChangeFrameOf(gameTime, FrameList.Count - (_FrameDead + _FrameChangeStt), FrameList.Count - _FrameDead - 1, 150);
            if (ActiveFrame == FrameList.Count - _FrameDead - 1)
            {
                ActiveFrame = 15;
                Move = true;
                HP--;
                Status = 2;
            }
        }

        //Khi đối tượng chết
        private void Dead(GameTime gameTime)
        {
            Move = false;
            ChangeFrameOf(gameTime, FrameList.Count - _FrameDead, FrameList.Count - 1, Config.TimeDead);
            if (ActiveFrame == FrameList.Count - 1) Enabled = false;
        }

        //Chuyển trạng thái của đối khi mất máu
        private void Change_Status(GameTime gameTime)
        {
            if (Immortal)
            {
                _ElapsedTimeImmortal += gameTime.ElapsedGameTime;
                if (_ElapsedTimeImmortal > TimeSpan.FromSeconds(2))
                {
                    _ElapsedTimeImmortal -= TimeSpan.FromSeconds(2);
                    _Immortal = false;
                }
            }

            if (Status == 1)
            {
                HpDown(gameTime);
            }

            if (Status == 4)
            {
                Move=false;
                if ((ActiveFrame + 1) % _HoriFrame != 0) ActiveFrame = _HoriFrame - 1;
                _ElapsedTimeChange += gameTime.ElapsedGameTime;
                if (_ElapsedTimeChange > TimeSpan.FromMilliseconds(60))
                {
                    _ElapsedTimeChange -= TimeSpan.FromMilliseconds(60);
                    ActiveFrame += _HoriFrame;
                    if (ActiveFrame > _HoriFrame * 8 - 1)
                    {
                        Move = true;
                        Status = 3;
                        ActiveFrame = _HoriFrame * 4 - 1;
                    }
                }
            }

            

        }

        //Giữ cho đối tượng không ra khỏi màn hình
        private bool KeepInBound()
        {
            bool temp = false;
            if (Position.X < -3)
            {
                _Position.X = -3;
                Move = false;
                temp = true;
            }
            if (Position.X + Width > 40 * 15)
            {
                _Position.X = 40 * 15 - Width;
                Move = false;
                temp = true;
            }

            if (Position.Y < -7)
            {
                _Position.Y = 0;
                Move = false;
                temp = true;
            }

            if (Position.Y + Height > 40 * 15)
            {
                _Position.Y = 40 * 15 - Height;
                Move = false;
                temp = true;
            }

            return temp;
        }

        protected virtual void UpdateStatus()
        {
        }

        public override void Update(GameTime gameTime)
        {
            if (!Enabled) return;
            UpdateStatus();
            if (HP <= 0)
            {
                Dead(gameTime);
            }
            KeepInBound();
            Change_Status(gameTime);
            if (Move) Position += Speed;

            base.Update(gameTime);
        }
    }
}
